package com.jfirer.jsql.starter;

import com.jfirer.jsql.SessionFactory;
import com.jfirer.jsql.SessionFactoryConfig;
import com.jfirer.jsql.dialect.Dialect;
import com.jfirer.jsql.executor.SqlExecutor;
import com.jfirer.jsql.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.List;

/**
 * JSql自动配置类
 */
@Configuration
@ConditionalOnClass({SessionFactory.class, SqlSession.class})
@EnableTransactionManagement
public class JSqlAutoConfiguration
{
    // 移除了transactionAwareJsqlDataSource bean的定义，因为现在在sessionFactory方法中动态处理事务感知能力

    @Bean
    @ConditionalOnMissingBean
    public SessionFactory sessionFactory(DataSource dataSource,//
                                         @Autowired(required = false) Dialect dialect,//
                                         @Autowired(required = false) List<SqlExecutor> sqlExecutors)
    {
        // 检查传入的DataSource是否已经是TransactionAwareDataSourceProxy的实例
        DataSource transactionAwareDataSource;
        if (dataSource instanceof TransactionAwareDataSourceProxy)
        {
            // 如果已经是TransactionAwareDataSourceProxy，则直接使用
            transactionAwareDataSource = dataSource;
        }
        else
        {
            // 否则，将其包装成TransactionAwareDataSourceProxy
            transactionAwareDataSource = new TransactionAwareDataSourceProxy(dataSource);
        }
        SessionFactoryConfig config = new SessionFactoryConfig();
        config.setDataSource(transactionAwareDataSource);
        if (dialect != null)
        {
            config.setDialect(dialect);
        }
        if (sqlExecutors != null)
        {
            for (SqlExecutor sqlExecutor : sqlExecutors)
            {
                config.addSqlExecutor(sqlExecutor);
            }
        }
        return config.build();
    }

    @Bean
    @ConditionalOnMissingBean
    public JSqlSessionSpringTemplate jSqlSessionSpringTemplate(SessionFactory sessionFactory)
    {
        return new JSqlSessionSpringTemplate(sessionFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    public ReadOnlySqlSession readOnlySqlSession(SessionFactory sessionFactory)
    {
        return new ReadOnlySqlSession(sessionFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    public PlatformTransactionManager transactionManager(DataSource dataSource)
    {
        // 确保使用的是原始的DataSource来创建事务管理器
        DataSource rawDataSource = dataSource;
        if (dataSource instanceof TransactionAwareDataSourceProxy)
        {
            rawDataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource();
        }
        return new DataSourceTransactionManager(rawDataSource);
    }
}